package spe.xml;

import java.beans.PropertyChangeEvent;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import spe.model.spem.MethodConfiguration;
import spe.model.spem.MethodLibrary;
import spe.model.spem.MethodPlugin;
import spe.model.spem.SPEMElement;

public class MethodLibraryAdapter extends SPEXmlAdapter
{
	private static String[] CHILD_ELEMENTS = {"method-plugin", "method-configuration"};
	
	private static final String INTER_NODE_TYPE_SPACING = "\n\n\n";
	private static final String INTER_CHILD_SPACING = "\n";
	
	@Override
	protected String getInterNodeTypeSpacing()
	{
		return INTER_NODE_TYPE_SPACING;
	}
	
	@Override
	protected String getInterChildSpacing()
	{
		return INTER_CHILD_SPACING;
	}
	
	@Override
	protected String[] getChildElements()
	{
		return CHILD_ELEMENTS;
	}
	
	@Override
	protected Map<String, String> getNodeTypes()
	{
		if (NODE_TYPES == null) 
		{
			NODE_TYPES = new HashMap<String, String>();
			NODE_TYPES.put("method-plugin", "method-plugin");
			NODE_TYPES.put("method-configuration", "method-configuration");
			NODE_TYPES.put("activity", "activity");
			NODE_TYPES.put("role-definition", "role-definition");
			NODE_TYPES.put("task-definition", "task-definition");
			NODE_TYPES.put("work-product-definition", "work-product-definition");
			NODE_TYPES.put("tool-definition", "tool-definition");
			NODE_TYPES.put("method-content-package", "method-content-package");
			NODE_TYPES.put("process-package", "process-package");
			
		}
		return NODE_TYPES;
	}

	@Override
	protected void initialize()
	{
		super.initialize();
		MethodLibrary ml = (MethodLibrary) getSemanticElement();
		String key;
		if(ml != null)
		{
			Map<String, Object> attrs = ml.getAttributes();
			Iterator<String> iter = attrs.keySet().iterator();
			while(iter.hasNext())
			{
				key = iter.next();
				setAttribute(key, attrs.get(key).toString());
			}
			
			if(ml.getOwnedConfigurations() != null)
				addElements(ml.getOwnedConfigurations().toArray(new MethodConfiguration[ml.getOwnedConfigurations().size()]));
			
			if(ml.getOwnedMethodPlugins() != null)
				addElements(ml.getOwnedMethodPlugins().toArray(new MethodPlugin[ml.getOwnedMethodPlugins().size()]));
		}
		//System.out.println(String.format("[MethodLibraryAdapter] initialize()"));
	}
	
	@Override
	public void initialize(SPEMElement speElement)
	{
		super.initialize(speElement);
		MethodLibrary ml = (MethodLibrary) getSemanticElement();
		Map<String, String> attrbMap = getAttributes();
		Iterator<String> iterAtts = attrbMap.keySet().iterator();
		String nextAttr;
		while(iterAtts.hasNext())
		{
			nextAttr = iterAtts.next();
			if("name".equals(nextAttr))
				ml.setName(getAttribute("name"));
			
			if("id".equals(nextAttr))
				ml.setName(getAttribute("id"));
		}
		speElement.addPropertyChangeListener(this);
	}
	
	@Override
	protected void doModelUpdate(String name, String newValue) 
	{
		// TODO Auto-generated method stub
	}

	@Override
	protected void doModelAdd(SPEXmlAdapter child) 
	{
		String type = child.getElementType();
		SPEMElement childElement = null;
		MethodLibrary ml = (MethodLibrary) this.getSemanticElement();
		
		if("method-configuration".equals(type) || "method-plugin".equals(type))
		{
			childElement = createSemanticElementFor(child);
			ml.addChildElement(childElement);
			childElement.setParent(ml);
		}

		//System.out.println(String.format("[MethodLibraryAdapter] Child Element: %s", childElement));
		
		child.initialize(childElement);
		
	}

	@Override
	protected void doModelRemove(SPEXmlAdapter child) {
		// TODO Auto-generated method stub
		
	}

	@Override
	protected void doPropertyChange(PropertyChangeEvent event) 
	{
		String propertyName = event.getPropertyName();
		if(propertyName.equals("Element"))
		{
			SPEMElement e = (SPEMElement) event.getNewValue();
			addElement(e);
			//System.out.println(String.format("[MethodLibraryAdapter] Child Element: %s", e));
		}
		else if( propertyName.equals("name") || propertyName.equals("id") )
		{
			setAttribute(propertyName, event.getNewValue().toString());
		}
	}

}
